Micron Document
C.S.Burner 🪙 ━►🔥GIT Node

Node / reticulum_mirror / MeshChatX / files / tests / backend / test_http_auth_security.py

Displaying Raw • Download

tests/backend/test_http_auth_security.py dev (25212991) Text, 11.06 KB

T8b949e# SPDX-License-Identifier: 0BSD

Tff7b72import T7ee787asyncio
Tff7b72import T7ee787secrets
Tff7b72from T7ee787unittestT7ee787.T7ee787mock Tff7b72import Te6edf3AsyncMockTb4b4b4, Te6edf3MagicMockTb4b4b4, Te6edf3patch

Tff7b72import T7ee787bcrypt
Tff7b72import T7ee787pytest
Tff7b72from T7ee787aiohttp Tff7b72import Te6edf3web
Tff7b72from T7ee787aiohttpT7ee787.T7ee787test_utils Tff7b72import Te6edf3TestClientTb4b4b4, Te6edf3TestServer
Tff7b72from T7ee787aiohttp_session Tff7b72import Te6edf3setup Tff7b72as Te6edf3setup_session
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3HealthCheckTb4b4b4, Te6edf3givenTb4b4b4, Te6edf3settings
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3strategies Tff7b72as Te6edf3st

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787config_manager Tff7b72import Te6edf3ConfigManager
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787httpT7ee787.T7ee787middleware Tff7b72import Te6edf3create_auth_middleware
Tff7b72from T7ee787testsT7ee787.T7ee787backendT7ee787.T7ee787conftest Tff7b72import Te6edf3extend_meshchat_middlewaresTb4b4b4, Te6edf3fetch_api_csrf_headers


Tff7b72def Td2a8ff_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTb4b4b4: Tffa657boolTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffsession_secret_key Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_urlsafeTb4b4b4(T79c0ff32Tb4b4b4)
Te6edf3mock_appTff7b72.Td2a8fflisten_host Tff7b72= Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"
Te6edf3mock_appTff7b72.Td2a8fflisten_port Tff7b72= T79c0ff8000
Te6edf3mock_appTff7b72.Td2a8ffuse_https Tff7b72= Te6edf3use_https
Te6edf3mock_appTff7b72.Td2a8fflandlock_active Tff7b72= Tff7b72False
Te6edf3routes Tff7b72= Te6edf3webTff7b72.Td2a8ffRouteTableDefTb4b4b4(Tb4b4b4)
Te6edf3middlewares Tff7b72= Te6edf3mock_appTff7b72.Td2a8ff_define_routesTb4b4b4(Te6edf3routesTb4b4b4)
Te6edf3aio_app Tff7b72= Te6edf3webTff7b72.Td2a8ffApplicationTb4b4b4(Tb4b4b4)
Te6edf3setup_sessionTb4b4b4(Te6edf3aio_appTb4b4b4, Te6edf3mock_appTff7b72.Td2a8ff_encrypted_cookie_storageTb4b4b4(Te6edf3use_httpsTb4b4b4)Tb4b4b4)
Te6edf3extend_meshchat_middlewaresTb4b4b4(Te6edf3aio_appTb4b4b4, Te6edf3middlewaresTb4b4b4)
Te6edf3aio_appTff7b72.Td2a8ffadd_routesTb4b4b4(Te6edf3routesTb4b4b4)
Tff7b72return Te6edf3aio_app


Tff7b72def Td2a8fftest_config_password_hash_roundtripTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(Ta5d6ff"Ta5d6ffroundtrip-test-hashTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72== Ta5d6ff"Ta5d6ffroundtrip-test-hashTa5d6ff"


Tff7b72def Td2a8fftest_config_bcrypt_hash_roundtripTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3h Tff7b72= Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffpwTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(Te6edf3hTb4b4b4)
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72== Te6edf3h


Tff7b72def Td2a8fftest_encrypted_cookie_storage_https_flagsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffsession_secret_key Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_urlsafeTb4b4b4(T79c0ff32Tb4b4b4)
Te6edf3storage Tff7b72= Te6edf3mock_appTff7b72.Td2a8ff_encrypted_cookie_storageTb4b4b4(Tff7b72TrueTb4b4b4)
Tff7b72assert Te6edf3storageTff7b72.Td2a8ffcookie_paramsTb4b4b4[Ta5d6ff"Ta5d6ffsecureTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72True
Tff7b72assert Te6edf3storageTff7b72.Td2a8ffcookie_paramsTb4b4b4[Ta5d6ff"Ta5d6ffhttponlyTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72True
Tff7b72assert Te6edf3storageTff7b72.Td2a8ffcookie_paramsTb4b4b4[Ta5d6ff"Ta5d6ffsamesiteTa5d6ff"Tb4b4b4] Tff7b72== Ta5d6ff"Ta5d6ffLaxTa5d6ff"


Tff7b72def Td2a8fftest_encrypted_cookie_storage_http_flagsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffsession_secret_key Tff7b72= Te6edf3secretsTff7b72.Td2a8fftoken_urlsafeTb4b4b4(T79c0ff32Tb4b4b4)
Te6edf3storage Tff7b72= Te6edf3mock_appTff7b72.Td2a8ff_encrypted_cookie_storageTb4b4b4(Tff7b72FalseTb4b4b4)
Tff7b72assert Te6edf3storageTff7b72.Td2a8ffcookie_paramsTb4b4b4[Ta5d6ff"Ta5d6ffsecureTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72False


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fftest_login_sets_cookie_and_allows_protected_apiTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3pw Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6ffintegration-test-password-okTa5d6ff"
Te6edf3stored_hash Tff7b72= Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Te6edf3pwTb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(Te6edf3stored_hashTb4b4b4)
Tff7b72assert Tffa657isinstanceTb4b4b4(Te6edf3mock_appTff7b72.Td2a8ffcurrent_contextTff7b72.Td2a8ffconfigTb4b4b4, Te6edf3ConfigManagerTb4b4b4)
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72== Te6edf3stored_hash
Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3headers Tff7b72= Tff7b72await Te6edf3fetch_api_csrf_headersTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3login Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffpostTb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/auth/loginTa5d6ff"Tb4b4b4,
Te6edf3jsonTff7b72=Tb4b4b4{Ta5d6ff"Ta5d6ffpasswordTa5d6ff"Tb4b4b4: Te6edf3pwTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4,
Te6edf3headersTff7b72=Te6edf3headersTb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3loginTff7b72.Td2a8ffstatus Tff7b72== T79c0ff200
Te6edf3set_cookie Tff7b72= Te6edf3loginTff7b72.Td2a8ffheadersTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffSet-CookieTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffHttpOnlyTa5d6ff" Tff7b72in Te6edf3set_cookie
Tff7b72assert Ta5d6ff"Ta5d6ffSameSite=LaxTa5d6ff" Tff7b72in Te6edf3set_cookie
Tff7b72assert Ta5d6ff"Ta5d6ffSecureTa5d6ff" Tff7b72not Tff7b72in Te6edf3set_cookie

Te6edf3backups Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/database/backupsTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3backupsTff7b72.Td2a8ffstatus Tff7b72== T79c0ff200
Te6edf3body Tff7b72= Tff7b72await Te6edf3backupsTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffbackupsTa5d6ff" Tff7b72in Te6edf3body


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fftest_ws_returns_401_without_session_when_auth_enabledTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(
Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffxTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3r Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/wsTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3rTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fftest_logout_clears_session_for_protected_apiTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3pw Tff7b72= Ta5d6ffbTa5d6ff"Ta5d6fflogout-test-password-okTa5d6ff"
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(
Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Te6edf3pwTb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3headers Tff7b72= Tff7b72await Te6edf3fetch_api_csrf_headersTb4b4b4(Te6edf3clientTb4b4b4)
Tff7b72await Te6edf3clientTff7b72.Td2a8ffpostTb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/auth/loginTa5d6ff"Tb4b4b4,
Te6edf3jsonTff7b72=Tb4b4b4{Ta5d6ff"Ta5d6ffpasswordTa5d6ff"Tb4b4b4: Te6edf3pwTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4}Tb4b4b4,
Te6edf3headersTff7b72=Te6edf3headersTb4b4b4,
Tb4b4b4)
Tff7b72assert Tb4b4b4(Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/database/backupsTa5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffstatus Tff7b72== T79c0ff200

Te6edf3headers Tff7b72= Tff7b72await Te6edf3fetch_api_csrf_headersTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3out Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffpostTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/auth/logoutTa5d6ff"Tb4b4b4, Te6edf3headersTff7b72=Te6edf3headersTb4b4b4)
Tff7b72assert Te6edf3outTff7b72.Td2a8ffstatus Tff7b72== T79c0ff200

Tff7b72assert Tb4b4b4(Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/database/backupsTa5d6ff"Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffstatus Tff7b72== T79c0ff401


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fftest_auth_login_invalid_json_returns_400Tb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(
Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffxTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3headers Tff7b72= Tff7b72await Te6edf3fetch_api_csrf_headersTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3r Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffpostTb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/auth/loginTa5d6ff"Tb4b4b4,
Te6edf3dataTff7b72=Ta5d6ff"Ta5d6ff{Ta5d6ffnot-jsonTa5d6ff"Tb4b4b4,
Te6edf3headersTff7b72=Tb4b4b4{Tff7b72*Tff7b72*Te6edf3headersTb4b4b4, Ta5d6ff"Ta5d6ffContent-TypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffapplication/jsonTa5d6ff"Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3rTff7b72.Td2a8ffstatus Tff7b72== T79c0ff400
Te6edf3body Tff7b72= Tff7b72await Te6edf3rTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6fferrorTa5d6ff" Tff7b72in Te6edf3body


Tf0883e@settingsTb4b4b4(
Te6edf3max_examplesTff7b72=T79c0ff40Tb4b4b4,
Te6edf3suppress_health_checkTff7b72=Tb4b4b4[Te6edf3HealthCheckTff7b72.Td2a8fffunction_scoped_fixtureTb4b4b4]Tb4b4b4,
Te6edf3deadlineTff7b72=Tff7b72NoneTb4b4b4,
Tb4b4b4)
Tf0883e@givenTb4b4b4(Te6edf3bodyTff7b72=Te6edf3stTff7b72.Td2a8ffbinaryTb4b4b4(Te6edf3min_sizeTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_sizeTff7b72=T79c0ff12000Tb4b4b4)Tb4b4b4)
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8fftest_auth_login_fuzz_never_500Tb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3bodyTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(
Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6fffixedTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72async Tff7b72def Td2a8ffrunTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3headers Tff7b72= Tff7b72await Te6edf3fetch_api_csrf_headersTb4b4b4(Te6edf3clientTb4b4b4)
Te6edf3r Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffpostTb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/auth/loginTa5d6ff"Tb4b4b4,
Te6edf3dataTff7b72=Te6edf3bodyTb4b4b4,
Te6edf3headersTff7b72=Tb4b4b4{Tff7b72*Tff7b72*Te6edf3headersTb4b4b4, Ta5d6ff"Ta5d6ffContent-TypeTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffapplication/jsonTa5d6ff"Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3rTff7b72.Td2a8ffstatus Tff7b72!= T79c0ff500

Te6edf3asyncioTff7b72.Td2a8ffrunTb4b4b4(Te6edf3runTb4b4b4(Tb4b4b4)Tb4b4b4)


Tff7b72def Td2a8fftest_reset_password_clears_hash_when_setTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3h Tff7b72= Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffold-passwordTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(Te6edf3hTb4b4b4)
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffreset_passwordTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72None


Tff7b72def Td2a8fftest_reset_password_no_op_when_no_hashTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(Tff7b72NoneTb4b4b4)
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffreset_passwordTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72None


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fftest_reset_password_exposes_setup_screenTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3h Tff7b72= Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffold-passwordTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(Te6edf3hTb4b4b4)
Tff7b72assert Te6edf3mock_appTff7b72.Td2a8ffreset_passwordTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True

Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3status Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/auth/statusTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3statusTff7b72.Td2a8ffstatus Tff7b72== T79c0ff200
Te6edf3body Tff7b72= Tff7b72await Te6edf3statusTff7b72.Td2a8ffjsonTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3bodyTb4b4b4[Ta5d6ff"Ta5d6ffpassword_setTa5d6ff"Tb4b4b4] Tff7b72is Tff7b72False


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffusefixturesTb4b4b4(Ta5d6ff"Ta5d6ffrequire_loopback_tcpTa5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8fftest_auth_rejects_api_paths_that_end_with_static_extensionsTb4b4b4(Te6edf3mock_appTb4b4b4)Tb4b4b4:
T8b949e"""Unauthenticated /api/v1 paths must 401 even when the URL looks like a static file.

Plugin assets are /api/v1/plugins/{id}/asset/{path} and commonly end in
.js/.json/.wasm. Those suffixes are public only for non-API static files.
"""
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_enabledTff7b72.Td2a8ffsetTb4b4b4(Tff7b72TrueTb4b4b4)
Te6edf3mock_appTff7b72.Td2a8ffconfigTff7b72.Td2a8ffauth_password_hashTff7b72.Td2a8ffsetTb4b4b4(
Te6edf3bcryptTff7b72.Td2a8ffhashpwTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffxTa5d6ff"Tb4b4b4, Te6edf3bcryptTff7b72.Td2a8ffgensaltTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3aio_app Tff7b72= Te6edf3_make_aio_appTb4b4b4(Te6edf3mock_appTb4b4b4, Te6edf3use_httpsTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72async Tff7b72with Te6edf3TestClientTb4b4b4(Te6edf3TestServerTb4b4b4(Te6edf3aio_appTb4b4b4)Tb4b4b4) Tff7b72as Te6edf3clientTb4b4b4:
Te6edf3config Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/configTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3configTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401

Te6edf3disguised Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/config.jsonTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3disguisedTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401Tb4b4b4, Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffexpected 401 for disguised API path, got Tffd700{Te6edf3disguisedTff7b72.Td2a8ffstatusTffd700}Ta5d6ff"
Tb4b4b4)

Te6edf3plugin_js Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/plugins/com.meshchatx.mcx-bugs/asset/frontend/main.jsTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3plugin_jsTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401Tb4b4b4, Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffexpected 401 for plugin JS asset, got Tffd700{Te6edf3plugin_jsTff7b72.Td2a8ffstatusTffd700}Ta5d6ff"
Tb4b4b4)

Te6edf3plugin_wasm Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/plugins/com.meshchatx.mcx-bugs/asset/backend/main.wasmTa5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3plugin_wasmTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401Tb4b4b4, Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffexpected 401 for plugin wasm asset, got Tffd700{Te6edf3plugin_wasmTff7b72.Td2a8ffstatusTffd700}Ta5d6ff"
Tb4b4b4)

Te6edf3status_prefix Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/api/v1/status.jsonTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3status_prefixTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401Tb4b4b4, Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffexpected 401 for status prefix disguise, got Tffd700{Te6edf3status_prefixTff7b72.Td2a8ffstatusTffd700}Ta5d6ff"
Tb4b4b4)

T8b949e# Do not GET /manifest.json here. That route uses FileResponse, which
T8b949e# calls loop.run_in_executor. mock_app patches threading.Thread so the
T8b949e# executor never runs and the client hangs until TimeoutError.
T8b949e# A missing static asset is enough: middleware must not 401 it.
Te6edf3static_js Tff7b72= Tff7b72await Te6edf3clientTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ff/assets/does-not-exist.jsTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3static_jsTff7b72.Td2a8ffstatus Tff7b72!= T79c0ff401Tb4b4b4, Tb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffexpected static non-API path to skip auth, got Tffd700{Te6edf3static_jsTff7b72.Td2a8ffstatusTffd700}Ta5d6ff"
Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffasyncio
Tff7b72async Tff7b72def Td2a8fftest_auth_middleware_does_not_treat_api_static_suffixes_as_publicTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e"""Oracle: password auth still applies when an API path ends in .js/.json/.wasm."""
Te6edf3app Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3appTff7b72.Td2a8ffauth_enabled Tff7b72= Tff7b72True
Te6edf3appTff7b72.Td2a8ffcurrent_context Tff7b72= Te6edf3MagicMockTb4b4b4(Te6edf3runningTff7b72=Tff7b72TrueTb4b4b4)
Te6edf3appTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTff7b72.Td2a8ffhexTff7b72.Td2a8ffreturn_value Tff7b72= Ta5d6ff"Ta5d6ffaaTa5d6ff" Tff7b72* T79c0ff16
Te6edf3appTff7b72.Td2a8ff_startup_stage Tff7b72= Ta5d6ff"Ta5d6ffokTa5d6ff"

Te6edf3handler Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3return_valueTff7b72=Te6edf3webTff7b72.Td2a8ffResponseTb4b4b4(Te6edf3statusTff7b72=T79c0ff200Tb4b4b4, Te6edf3textTff7b72=Ta5d6ff"Ta5d6ffokTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3mw Tff7b72= Te6edf3create_auth_middlewareTb4b4b4(Te6edf3appTb4b4b4)
Te6edf3empty_session Tff7b72= Te6edf3AsyncMockTb4b4b4(Te6edf3return_valueTff7b72=Tb4b4b4{Tb4b4b4}Tb4b4b4)

Tff7b72async Tff7b72def Td2a8ffcallTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Te6edf3request Tff7b72= Te6edf3MagicMockTb4b4b4(Tb4b4b4)
Te6edf3requestTff7b72.Td2a8ffpath Tff7b72= Te6edf3path
Tff7b72with Te6edf3patchTb4b4b4(
Ta5d6ff"Ta5d6ffmeshchatx.src.backend.http.middleware.get_sessionTa5d6ff"Tb4b4b4,
Te6edf3empty_sessionTb4b4b4,
Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72await Te6edf3mwTb4b4b4(Te6edf3requestTb4b4b4, Te6edf3handlerTb4b4b4)

Tff7b72for Te6edf3path Tff7b72in Tb4b4b4(
Ta5d6ff"Ta5d6ff/api/v1/config.jsonTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff/api/v1/status.jsonTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff/api/v1/plugins/com.meshchatx.mcx-bugs/asset/frontend/main.jsTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff/api/v1/plugins/com.meshchatx.mcx-bugs/asset/backend/main.wasmTa5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3handlerTff7b72.Td2a8ffreset_mockTb4b4b4(Tb4b4b4)
Te6edf3resp Tff7b72= Tff7b72await Te6edf3callTb4b4b4(Te6edf3pathTb4b4b4)
Tff7b72assert Te6edf3respTff7b72.Td2a8ffstatus Tff7b72== T79c0ff401Tb4b4b4, Ta5d6fffTa5d6ff"Tffd700{Te6edf3pathTffd700}Ta5d6ff expected 401, got Tffd700{Te6edf3respTff7b72.Td2a8ffstatusTffd700}Ta5d6ff"
Te6edf3handlerTff7b72.Td2a8ffassert_not_awaitedTb4b4b4(Tb4b4b4)

Te6edf3handlerTff7b72.Td2a8ffreset_mockTb4b4b4(Tb4b4b4)
Te6edf3public Tff7b72= Tff7b72await Te6edf3callTb4b4b4(Ta5d6ff"Ta5d6ff/manifest.jsonTa5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3publicTff7b72.Td2a8ffstatus Tff7b72== T79c0ff200
Te6edf3handlerTff7b72.Td2a8ffassert_awaited_onceTb4b4b4(Tb4b4b4)

Served by rngit 1.4.2 - Generated in 0.04s